const redis = require('redis');

class CacheManager {
  constructor() {
    this.client = null;
    this.isConnected = false;
    this.init();
  }

  async init() {
    try {
      // 创建Redis客户端
      this.client = redis.createClient({
        host: process.env.REDIS_HOST || 'localhost',
        port: process.env.REDIS_PORT || 6379,
        password: process.env.REDIS_PASSWORD || undefined,
        db: process.env.REDIS_DB || 0,
        retry_strategy: (options) => {
          if (options.error && options.error.code === 'ECONNREFUSED') {
            console.log('Redis连接被拒绝');
            return new Error('Redis连接被拒绝');
          }
          if (options.total_retry_time > 1000 * 60 * 60) {
            console.log('Redis重试时间超时');
            return new Error('Redis重试时间超时');
          }
          if (options.attempt > 10) {
            console.log('Redis重试次数超限');
            return undefined;
          }
          return Math.min(options.attempt * 100, 3000);
        }
      });

      this.client.on('connect', () => {
        console.log('Redis客户端连接成功');
        this.isConnected = true;
      });

      this.client.on('error', (err) => {
        console.error('Redis连接错误:', err);
        this.isConnected = false;
      });

      this.client.on('end', () => {
        console.log('Redis连接断开');
        this.isConnected = false;
      });

    } catch (error) {
      console.error('Redis初始化失败:', error);
      this.isConnected = false;
    }
  }

  // 设置缓存
  async set(key, value, ttl = 300) {
    if (!this.isConnected || !this.client) {
      console.warn('Redis未连接，跳过缓存设置');
      return false;
    }

    try {
      const serializedValue = JSON.stringify(value);
      if (ttl > 0) {
        await this.client.setex(key, ttl, serializedValue);
      } else {
        await this.client.set(key, serializedValue);
      }
      return true;
    } catch (error) {
      console.error('设置缓存失败:', error);
      return false;
    }
  }

  // 获取缓存
  async get(key) {
    if (!this.isConnected || !this.client) {
      console.warn('Redis未连接，跳过缓存获取');
      return null;
    }

    try {
      const value = await this.client.get(key);
      if (value) {
        return JSON.parse(value);
      }
      return null;
    } catch (error) {
      console.error('获取缓存失败:', error);
      return null;
    }
  }

  // 删除缓存
  async del(key) {
    if (!this.isConnected || !this.client) {
      return false;
    }

    try {
      await this.client.del(key);
      return true;
    } catch (error) {
      console.error('删除缓存失败:', error);
      return false;
    }
  }

  // 批量删除缓存（支持通配符）
  async delPattern(pattern) {
    if (!this.isConnected || !this.client) {
      return false;
    }

    try {
      const keys = await this.client.keys(pattern);
      if (keys.length > 0) {
        await this.client.del(...keys);
      }
      return true;
    } catch (error) {
      console.error('批量删除缓存失败:', error);
      return false;
    }
  }

  // 检查缓存是否存在
  async exists(key) {
    if (!this.isConnected || !this.client) {
      return false;
    }

    try {
      const result = await this.client.exists(key);
      return result === 1;
    } catch (error) {
      console.error('检查缓存存在性失败:', error);
      return false;
    }
  }

  // 设置缓存过期时间
  async expire(key, ttl) {
    if (!this.isConnected || !this.client) {
      return false;
    }

    try {
      await this.client.expire(key, ttl);
      return true;
    } catch (error) {
      console.error('设置缓存过期时间失败:', error);
      return false;
    }
  }

  // 获取缓存剩余过期时间
  async ttl(key) {
    if (!this.isConnected || !this.client) {
      return -1;
    }

    try {
      return await this.client.ttl(key);
    } catch (error) {
      console.error('获取缓存过期时间失败:', error);
      return -1;
    }
  }

  // 关闭连接
  async close() {
    if (this.client) {
      await this.client.quit();
      this.isConnected = false;
    }
  }
}

// 创建单例实例
const cacheManager = new CacheManager();

// 缓存键生成器
const CacheKeys = {
  // 商品相关
  PRODUCT_LIST: (params) => `product:list:${JSON.stringify(params)}`,
  PRODUCT_DETAIL: (id) => `product:detail:${id}`,
  PRODUCT_CATEGORIES: () => 'product:categories',
  PRODUCT_BRANDS: () => 'product:brands',

  // 店铺相关
  SHOP_LIST: (params) => `shop:list:${JSON.stringify(params)}`,
  SHOP_DETAIL: (id) => `shop:detail:${id}`,
  SHOP_PRODUCTS: (shopId, params) => `shop:${shopId}:products:${JSON.stringify(params)}`,

  // 统计相关
  DASHBOARD_STATS: () => 'dashboard:stats',
  SALES_TREND: (period) => `sales:trend:${period}`,

  // 用户相关
  USER_PROFILE: (id) => `user:profile:${id}`,

  // 订单相关
  ORDER_STATS: (period) => `order:stats:${period}`,
};

// 缓存装饰器函数
function withCache(keyGenerator, ttl = 300) {
  return function (target, propertyName, descriptor) {
    const method = descriptor.value;

    descriptor.value = async function (...args) {
      const cacheKey = keyGenerator(...args);

      // 尝试从缓存获取
      const cachedResult = await cacheManager.get(cacheKey);
      if (cachedResult) {
        if (process.env.ENABLE_CACHE_LOGS === 'true') {
          console.log(`💾 缓存命中: ${cacheKey}`);
        }
        return cachedResult;
      }

      // 执行原方法
      const result = await method.apply(this, args);

      // 设置缓存
      await cacheManager.set(cacheKey, result, ttl);
      if (process.env.ENABLE_CACHE_LOGS === 'true') {
        console.log(`💾 缓存设置: ${cacheKey}`);
      }

      return result;
    };

    return descriptor;
  };
}

module.exports = {
  cacheManager,
  CacheKeys,
  withCache
};
